// 获取ip+port
export const getUrlIpPort = () => {
  var protocol = document.location.protocol
  var url = protocol + '//' + document.location.hostname

  if (document.location.port) {
    url = url + ':' + document.location.port
  } else {
    if (protocol === 'https:') {
      url = url + ':443'
    } else if (protocol === 'http:') {
      url = url + ':80'
    }
  }
  return url
}
/**
 * 违法详情页跳转
 * */
export const gotoDetail = params => {
  const ip = getUrlIpPort()
  var url = `${ip}/${process.env.VUE_APP_CONTEXT}/#/detail`
  console.log(url)
  // var url = `https://43.123.0.65/${process.env.VUE_APP_CONTEXT}/detail`
  const param = {
    componentId: '',
    componentMenuId: '',
    param: '',
    url: url,
    name: '多维查询详情',
    callback: {
      func: 'vpsIllegalDetail',
      param: params,
    },
    reload: true,
  }
  top.window.goToApp(param)
}
/* 工具类 */
/*
 * 随机数，10位时间戳 连接4位随机整数 e.g. 1428910956 + "" +3482
 * */
export const random14 = () => {
  return Math.round(new Date().getTime() / 1000) + '' + Math.floor(Math.random() * 9000 + 1000)
}

/**
 * @summary 千分位数字/金额
 * @param {number} money 数字/金额
 * @param {number} places 小数点位数，默认为2 (有则展示，无则不展示，优先级大于forcePlaces)
 * @param {number} forcePlaces 强制保留小数点位数，默认为0，<=0 为不强制保留（保留places位小数点，当长度不足forcePlaces时，用0补足）
 * @param {string} sysmbol 货币符号，默认为''
 * @param {boolean} thousand 是否千分位，默认为true
 * @returns {string}
 * @example
 *  thousandth(2222.2222) => 2,222.22 // 默认
 *  thousandth(2222.2, 2, 2, '$') => $2,222.20 // 强制保留小数点位数2
 *  thousandth(2222.2222, 0) => 2,222 // 不保留小数
 *  thousandth(2222.2222, 2, 0, '', false) => 2222.22 // 不千分位
 *  thousandth(2222.2222, 999) => 2,222.2222 // 保留所有小数
 */
export const thousandth = (money, places = 2, forcePlaces = 0, sysmbol = '', thousand = true) => {
  if (isNaN(money)) return money
  money = `${money}`
  const left = money.split('.')[0] // 小数点左边部分
  let right = money.split('.')[1] // 小数点右边
  if (places <= 0) {
    // 不保留小数
    right = ''
  } else if (forcePlaces > 0) {
    // 保留forcePlaces位小数点，当长度没有到places时，用0补足。
    right =
      '.' +
      (right
        ? right.length >= forcePlaces
          ? right.substr(0, forcePlaces)
          : right + '0'.repeat(forcePlaces - right.length)
        : '0'.repeat(forcePlaces))
  } else {
    if (right) {
      // 小数点位数，默认为2 (有则展示，无则不展示)
      right = right.length >= places ? '0.' + right.substr(0, places) : '0.' + right
      // 处理小数最后一位 为 0 的情况（强制保留的情况已经通过forcePlaces > 0处理了）
      right = Number(right) + '' // e.g. '0.30' => '0.3'
      right = right.substr(1, right.length)
    } else {
      right = ''
    }
    // right = right ? (right.length >= places ? '.' + right.substr(0, places) : '.' + right) : ''
  }
  if (thousand) {
    // 分割反向转为字符串然后最多3个，最少1个，将匹配的值放进数组返回
    const temp = left
      .split('')
      .reverse()
      .join('')
      .match(/(\d{1,3})/g)
    // 补齐正负号和货币符号，数组转为字符串，通过逗号分隔，再分割（包含逗号也分割）反向转为字符串变回原来的顺序
    return (Number(money) < 0 ? '-' : '') + sysmbol + temp.join(',').split('').reverse().join('') + right
  } else {
    return left + right
  }
}

/**
 * @summary 根据时间及格式获取时间的字符串
 * @param {int} iDate 时间
 * @param {string} sFormat 格式，默认：yyyy-MM-dd HH:mm:ss
 * @return {string} 格式化后的日期字符串
 * @example
 *    formatDate(new Date(),'yyyy-MM-dd HH:mm:ss SSS');// 2017-6-6 11:11:11
 */
export const formatDate = (iDate, sFormat = 'yyyy-MM-dd HH:mm:ss') => {
  if (!iDate) {
    return ''
  }
  if (typeof iDate === 'string') {
    iDate = iDate.replace(/-/g, '/')
  }
  const dDate = new Date(iDate)
  const year = dDate.getFullYear() // 年
  let month = dDate.getMonth() + 1 // 月
  if (month < 10) {
    month = '0' + month
  }
  let date = dDate.getDate() // 日
  if (date < 10) {
    date = '0' + date
  }
  let hour = dDate.getHours() // 时
  if (hour < 10) {
    hour = '0' + hour
  }
  let minute = dDate.getMinutes() // 分
  if (minute < 10) {
    minute = '0' + minute
  }
  let second = dDate.getSeconds() // 秒
  if (second < 10) {
    second = '0' + second
  }
  const millisecond = dDate.getMilliseconds() // 毫秒
  if (sFormat.indexOf('yyyy') >= 0) {
    sFormat = sFormat.replace('yyyy', year + '')
  }
  if (sFormat.indexOf('yy') >= 0) {
    sFormat = sFormat.replace('yy', (year + '').slice(2, 4))
  }
  if (sFormat.indexOf('MM') >= 0) {
    sFormat = sFormat.replace('MM', month + '')
  }
  if (sFormat.indexOf('dd') >= 0) {
    sFormat = sFormat.replace('dd', date + '')
  }
  if (sFormat.indexOf('HH') >= 0) {
    sFormat = sFormat.replace('HH', hour + '')
  }
  if (sFormat.indexOf('mm') >= 0) {
    sFormat = sFormat.replace('mm', minute + '')
  }
  if (sFormat.indexOf('ss') >= 0) {
    sFormat = sFormat.replace('ss', second + '')
  }
  if (sFormat.indexOf('SSS') >= 0) {
    sFormat = sFormat.replace('SSS', millisecond + '')
  }
  return sFormat
}

/**
 * @summary 使用post方式来导出文件
 * @param {Object} params 导出的参数
 * @param {String} url 导出的请求地址
 */
export const postExportFn = (params, url) => {
  var form = document.createElement('form')
  form.style.display = 'none'
  form.action = url
  form.method = 'post'
  document.body.appendChild(form)
  for (var key in params) {
    var input = document.createElement('input')
    input.type = 'hidden'
    input.name = key
    input.value = params[key]
    form.appendChild(input)
  }
  form.submit()
  form.remove()
}

/**
 * @summary 根据key从对象数组中拿对象
 * @param {array} list 对象数组
 * @param {string} key
 * @param {string} keyName
 * @return {Object} 返回对象 / NULL
 * @example
 */
export const getObjFromArrayByKey = (list, key, keyName) => {
  let _o = null
  if (!list || list.length <= 0) {
    return _o
  }
  for (let i = 0; i < list.length; i++) {
    if (key === list[i][keyName]) {
      _o = list[i]
      break
    }
  }
  return _o
}

/**
 * @summary 根据key从对象数组中拿对象
 * @param {array} list 对象数组
 * @param {string} key
 * @param {string} keyName
 * @param {string} keyName
 * @return {Number|String|Boolean} 返回值 / NULL
 * @example
 */
export const getValFromArrayByKey = (list, key, keyName, valName) => {
  if (!list || list.length <= 0) {
    return null
  }
  let _val = null
  for (let i = 0; i < list.length; i++) {
    if (key === list[i][keyName]) {
      _val = list[i][valName]
      break
    }
  }
  return _val
}

/**
 * @summary 该方法用于将有父子关系的数组转换成树形结构的数组
 * @param {Array} data 具有父子关系的数组
 * @param {Object} dataMode 数据模型 dataMode: { id: 'id', pid: 'pid', children: 'children'}
 * @param {Int | String} rootId 根节点ID
 * @return {Array} 树形结构的数组
 */
export const translateDataToTree = (data, dataMode, rootId) => {
  // 没有父节点的数据
  const parents = data.filter(value => !value[dataMode.pid] || value[dataMode.pid] === rootId)
  // parents.map(item => {
  //   item[dataMode.icon] = 'svg-city'
  // })
  // 有父节点的数据
  const children = data.filter(
    value =>
      value[dataMode.pid] !== undefined && value[dataMode.pid] != null && value[dataMode.pid] !== rootId,
  )
  // 定义转换方法的具体实现
  const translator = (parents, children) => {
    // 遍历父节点数据
    parents.forEach(parent => {
      // 遍历子节点数据
      children.forEach((current, index) => {
        // 此时找到父节点对应的一个子节点
        if (current[dataMode.pid] === parent[dataMode.id]) {
          // current[dataMode.icon] = 'svg-organization'
          // 对子节点数据进行深复制，这里只支持部分类型的数据深复制，对深复制不了解的童靴可以先去了解下深复制
          const temp = JSON.parse(JSON.stringify(children))
          // 让当前子节点从temp中移除，temp作为新的子节点数据，这里是为了让递归时，子节点的遍历次数更少，如果父子关系的层级越多，越有利
          temp.splice(index, 1)
          // 让当前子节点作为唯一的父节点，去递归查找其对应的子节点
          translator([current], temp)
          // 把找到子节点放入父节点的children属性中
          typeof parent.children !== 'undefined'
            ? parent.children.push(current)
            : (parent.children = [current])
        }
      })
    })
  }
  // 调用转换方法
  translator(parents, children)
  // 返回最终的结果
  return parents
}

/* 
JSON对象 深度合并
// 示例1
const obj1 = { x: { y: 1 }, z: [3, 4] }
const obj2 = { x: { z: 3 }, y: 2 }
console.log(deepMerge(obj1, obj2)) // 输出 { x: { y: 1, z: 3 }, y: 2, z: [3, 4] }

// 示例2
const obj3 = { x: { y: { z: 1 } }, w: [2] }
const obj4 = { x: { y: { w: 3 } }, z: 3 }
console.log(deepMerge(obj3, obj4)) // 输出 { x: { y: { z: 1, w: 3 } }, w: [2], z: 3 }
*/
export function deepMerge(target, source) {
  // 遍历源JSON对象
  for (const key of Object.keys(source)) {
    // 如果源对象当前属性是一个JSON对象，则递归地对其进行合并
    if (source[key] instanceof Object) {
      Object.assign(source[key], deepMerge(target[key], source[key]))
    }
  }
  // 合并所有属性
  return Object.assign({}, target, source)
}
